package org

import (
	"fmt"
	"sync/atomic"
	"time"

	"github.com/miscgo/sorm/model"
	"github.com/miscgo/sorm/model/user"
	"github.com/miscgo/sorm/singleton"
	"github.com/miscgo/sorm/util"
	"gorm.io/gorm"
)

var (
	orgId     int32 = 1000000
	orgIdStep int32 = 10
)

type OrganizationOrganization struct {
	Id                               int          `gorm:"column:id" json:"id" form:"id"`
	Created                          time.Time    `gorm:"column:created" json:"created" form:"created"`
	Updated                          time.Time    `gorm:"column:updated" json:"updated" form:"updated"`
	Name                             string       `gorm:"column:name" json:"name" form:"name"`
	Address                          string       `gorm:"column:address" json:"address" form:"address"`
	Phone                            string       `gorm:"column:phone" json:"phone" form:"phone"`
	Email                            string       `gorm:"column:email" json:"email" form:"email"`
	Established                      time.Time    `gorm:"column:established" json:"established" form:"established"`
	Brief                            string       `gorm:"column:brief" json:"brief" form:"brief"`
	Description                      string       `gorm:"column:description" json:"description" form:"description"`
	Solution                         string       `gorm:"column:solution" json:"solution" form:"solution"`
	Logo                             string       `gorm:"column:logo" json:"logo" form:"logo"`
	Is_provider                      bool         `gorm:"column:is_provider" json:"is_provider" form:"is_provider"`
	Is_active                        bool         `gorm:"column:is_active" json:"is_active" form:"is_active"`
	Status                           int          `gorm:"column:status" json:"status" form:"status"`
	Status_description               string       `gorm:"column:status_description" json:"status_description" form:"status_description"`
	Channel                          int          `gorm:"column:channel" json:"channel" form:"channel"`
	City_id                          int          `gorm:"column:city_id" json:"city_id" form:"city_id"`
	District_id                      int          `gorm:"column:district_id" json:"district_id" form:"district_id"`
	Owner_id                         int          `gorm:"column:owner_id" json:"owner_id" form:"owner_id"`
	Province_id                      int          `gorm:"column:province_id" json:"province_id" form:"province_id"`
	Supervisor_id                    int          `gorm:"column:supervisor_id" json:"supervisor_id" form:"supervisor_id"`
	Field_id                         int          `gorm:"column:field_id" json:"field_id" form:"field_id"`
	Nature                           int          `gorm:"column:nature" json:"nature" form:"nature"`
	Primary_contact_email            string       `gorm:"column:primary_contact_email" json:"primary_contact_email" form:"primary_contact_email"`
	Primary_contact_mobile           string       `gorm:"column:primary_contact_mobile" json:"primary_contact_mobile" form:"primary_contact_mobile"`
	Primary_contact_name             string       `gorm:"column:primary_contact_name" json:"primary_contact_name" form:"primary_contact_name"`
	Secondary_contact_email          string       `gorm:"column:secondary_contact_email" json:"secondary_contact_email" form:"secondary_contact_email"`
	Secondary_contact_mobile         string       `gorm:"column:secondary_contact_mobile" json:"secondary_contact_mobile" form:"secondary_contact_mobile"`
	Secondary_contact_name           string       `gorm:"column:secondary_contact_name" json:"secondary_contact_name" form:"secondary_contact_name"`
	Industry                         string       `gorm:"column:industry" json:"industry" form:"industry"`
	Credentials                      string       `gorm:"column:credentials" json:"credentials" form:"credentials"`
	Credit_code                      string       `gorm:"column:credit_code" json:"credit_code" form:"credit_code"`
	Legal_person                     string       `gorm:"column:legal_person" json:"legal_person" form:"legal_person"`
	Register_address                 string       `gorm:"column:register_address" json:"register_address" form:"register_address"`
	Sticky                           bool         `gorm:"column:sticky" json:"sticky" form:"sticky"`
	Certification_time               time.Time    `gorm:"column:certification_time" json:"certification_time" form:"certification_time"`
	Ppoi                             string       `gorm:"column:ppoi" json:"ppoi" form:"ppoi"`
	Is_deleted                       bool         `gorm:"column:is_deleted" json:"is_deleted" form:"is_deleted"`
	Activity_description             string       `gorm:"column:activity_description" json:"activity_description" form:"activity_description"`
	Activity_evaluation              string       `gorm:"column:activity_evaluation" json:"activity_evaluation" form:"activity_evaluation"`
	Activity_level                   string       `gorm:"column:activity_level" json:"activity_level" form:"activity_level"`
	Activity_score                   int          `gorm:"column:activity_score" json:"activity_score" form:"activity_score"`
	Development_speed_description    string       `gorm:"column:development_speed_description" json:"development_speed_description" form:"development_speed_description"`
	Development_speed_evaluation     string       `gorm:"column:development_speed_evaluation" json:"development_speed_evaluation" form:"development_speed_evaluation"`
	Development_speed_level          string       `gorm:"column:development_speed_level" json:"development_speed_level" form:"development_speed_level"`
	Development_speed_score          int          `gorm:"column:development_speed_score" json:"development_speed_score" form:"development_speed_score"`
	Evaluation_level                 string       `gorm:"column:evaluation_level" json:"evaluation_level" form:"evaluation_level"`
	Identity_description             string       `gorm:"column:identity_description" json:"identity_description" form:"identity_description"`
	Identity_evaluation              string       `gorm:"column:identity_evaluation" json:"identity_evaluation" form:"identity_evaluation"`
	Identity_level                   string       `gorm:"column:identity_level" json:"identity_level" form:"identity_level"`
	Identity_score                   int          `gorm:"column:identity_score" json:"identity_score" form:"identity_score"`
	Industry_strength_description    string       `gorm:"column:industry_strength_description" json:"industry_strength_description" form:"industry_strength_description"`
	Industry_strength_evaluation     string       `gorm:"column:industry_strength_evaluation" json:"industry_strength_evaluation" form:"industry_strength_evaluation"`
	Industry_strength_level          string       `gorm:"column:industry_strength_level" json:"industry_strength_level" form:"industry_strength_level"`
	Industry_strength_score          int          `gorm:"column:industry_strength_score" json:"industry_strength_score" form:"industry_strength_score"`
	Innovation_description           string       `gorm:"column:innovation_description" json:"innovation_description" form:"innovation_description"`
	Innovation_evaluation            string       `gorm:"column:innovation_evaluation" json:"innovation_evaluation" form:"innovation_evaluation"`
	Innovation_level                 string       `gorm:"column:innovation_level" json:"innovation_level" form:"innovation_level"`
	Innovation_score                 int          `gorm:"column:innovation_score" json:"innovation_score" form:"innovation_score"`
	Operating_risk_description       string       `gorm:"column:operating_risk_description" json:"operating_risk_description" form:"operating_risk_description"`
	Operating_risk_evaluation        string       `gorm:"column:operating_risk_evaluation" json:"operating_risk_evaluation" form:"operating_risk_evaluation"`
	Operating_risk_level             string       `gorm:"column:operating_risk_level" json:"operating_risk_level" form:"operating_risk_level"`
	Operating_risk_score             int          `gorm:"column:operating_risk_score" json:"operating_risk_score" form:"operating_risk_score"`
	Overall_score                    int          `gorm:"column:overall_score" json:"overall_score" form:"overall_score"`
	Manual_rating                    int          `gorm:"column:manual_rating" json:"manual_rating" form:"manual_rating"`
	Rating                           int          `gorm:"column:rating" json:"rating" form:"rating"`
	Total_views                      int          `gorm:"column:total_views" json:"total_views" form:"total_views"`
	Certification_status             int          `gorm:"column:certification_status" json:"certification_status" form:"certification_status"`
	Certification_status_description string       `gorm:"column:certification_status_description" json:"certification_status_description" form:"certification_status_description"`
	Is_published                     bool         `gorm:"column:is_published" json:"is_published" form:"is_published"`
	Location                         *model.Point `gorm:"column:location" json:"location" form:"location"`
	Source                           int          `gorm:"column:source" json:"source" form:"source"`
	Website                          string       `gorm:"column:website" json:"website" form:"website"`
	Org_type                         string       `gorm:"column:org_type" json:"org_type" form:"org_type"`
	Content_updated                  time.Time    `gorm:"column:content_updated" json:"content_updated" form:"content_updated"`
}

type PingOrganizationOrganization struct {
	Id                               int          `gorm:"column:id" json:"id" form:"id"`
	Created                          time.Time    `gorm:"column:created" json:"created" form:"created"`
	Updated                          time.Time    `gorm:"column:updated" json:"updated" form:"updated"`
	Name                             string       `gorm:"column:name" json:"name" form:"name"`
	Address                          string       `gorm:"column:address" json:"address" form:"address"`
	Phone                            string       `gorm:"column:phone" json:"phone" form:"phone"`
	Email                            string       `gorm:"column:email" json:"email" form:"email"`
	Established                      time.Time    `gorm:"column:established" json:"established" form:"established"`
	Brief                            string       `gorm:"column:brief" json:"brief" form:"brief"`
	Description                      string       `gorm:"column:description" json:"description" form:"description"`
	Solution                         string       `gorm:"column:solution" json:"solution" form:"solution"`
	Logo                             string       `gorm:"column:logo" json:"logo" form:"logo"`
	Is_provider                      bool         `gorm:"column:is_provider" json:"is_provider" form:"is_provider"`
	Is_active                        bool         `gorm:"column:is_active" json:"is_active" form:"is_active"`
	Status                           int          `gorm:"column:status" json:"status" form:"status"`
	Status_description               string       `gorm:"column:status_description" json:"status_description" form:"status_description"`
	Channel                          int          `gorm:"column:channel" json:"channel" form:"channel"`
	City_id                          int          `gorm:"column:city_id" json:"city_id" form:"city_id"`
	District_id                      int          `gorm:"column:district_id" json:"district_id" form:"district_id"`
	Owner_id                         int          `gorm:"column:owner_id" json:"owner_id" form:"owner_id"`
	Province_id                      int          `gorm:"column:province_id" json:"province_id" form:"province_id"`
	Supervisor_id                    int          `gorm:"column:supervisor_id" json:"supervisor_id" form:"supervisor_id"`
	Field_id                         int          `gorm:"column:field_id" json:"field_id" form:"field_id"`
	Nature                           int          `gorm:"column:nature" json:"nature" form:"nature"`
	Primary_contact_email            string       `gorm:"column:primary_contact_email" json:"primary_contact_email" form:"primary_contact_email"`
	Primary_contact_mobile           string       `gorm:"column:primary_contact_mobile" json:"primary_contact_mobile" form:"primary_contact_mobile"`
	Primary_contact_name             string       `gorm:"column:primary_contact_name" json:"primary_contact_name" form:"primary_contact_name"`
	Secondary_contact_email          string       `gorm:"column:secondary_contact_email" json:"secondary_contact_email" form:"secondary_contact_email"`
	Secondary_contact_mobile         string       `gorm:"column:secondary_contact_mobile" json:"secondary_contact_mobile" form:"secondary_contact_mobile"`
	Secondary_contact_name           string       `gorm:"column:secondary_contact_name" json:"secondary_contact_name" form:"secondary_contact_name"`
	Industry                         string       `gorm:"column:industry" json:"industry" form:"industry"`
	Credentials                      string       `gorm:"column:credentials" json:"credentials" form:"credentials"`
	Credit_code                      string       `gorm:"column:credit_code" json:"credit_code" form:"credit_code"`
	Legal_person                     string       `gorm:"column:legal_person" json:"legal_person" form:"legal_person"`
	Register_address                 string       `gorm:"column:register_address" json:"register_address" form:"register_address"`
	Sticky                           bool         `gorm:"column:sticky" json:"sticky" form:"sticky"`
	Certification_time               time.Time    `gorm:"column:certification_time" json:"certification_time" form:"certification_time"`
	Ppoi                             string       `gorm:"column:ppoi" json:"ppoi" form:"ppoi"`
	Is_deleted                       bool         `gorm:"column:is_deleted" json:"is_deleted" form:"is_deleted"`
	Activity_description             string       `gorm:"column:activity_description" json:"activity_description" form:"activity_description"`
	Activity_evaluation              string       `gorm:"column:activity_evaluation" json:"activity_evaluation" form:"activity_evaluation"`
	Activity_level                   string       `gorm:"column:activity_level" json:"activity_level" form:"activity_level"`
	Activity_score                   int          `gorm:"column:activity_score" json:"activity_score" form:"activity_score"`
	Development_speed_description    string       `gorm:"column:development_speed_description" json:"development_speed_description" form:"development_speed_description"`
	Development_speed_evaluation     string       `gorm:"column:development_speed_evaluation" json:"development_speed_evaluation" form:"development_speed_evaluation"`
	Development_speed_level          string       `gorm:"column:development_speed_level" json:"development_speed_level" form:"development_speed_level"`
	Development_speed_score          int          `gorm:"column:development_speed_score" json:"development_speed_score" form:"development_speed_score"`
	Evaluation_level                 string       `gorm:"column:evaluation_level" json:"evaluation_level" form:"evaluation_level"`
	Identity_description             string       `gorm:"column:identity_description" json:"identity_description" form:"identity_description"`
	Identity_evaluation              string       `gorm:"column:identity_evaluation" json:"identity_evaluation" form:"identity_evaluation"`
	Identity_level                   string       `gorm:"column:identity_level" json:"identity_level" form:"identity_level"`
	Identity_score                   int          `gorm:"column:identity_score" json:"identity_score" form:"identity_score"`
	Industry_strength_description    string       `gorm:"column:industry_strength_description" json:"industry_strength_description" form:"industry_strength_description"`
	Industry_strength_evaluation     string       `gorm:"column:industry_strength_evaluation" json:"industry_strength_evaluation" form:"industry_strength_evaluation"`
	Industry_strength_level          string       `gorm:"column:industry_strength_level" json:"industry_strength_level" form:"industry_strength_level"`
	Industry_strength_score          int          `gorm:"column:industry_strength_score" json:"industry_strength_score" form:"industry_strength_score"`
	Innovation_description           string       `gorm:"column:innovation_description" json:"innovation_description" form:"innovation_description"`
	Innovation_evaluation            string       `gorm:"column:innovation_evaluation" json:"innovation_evaluation" form:"innovation_evaluation"`
	Innovation_level                 string       `gorm:"column:innovation_level" json:"innovation_level" form:"innovation_level"`
	Innovation_score                 int          `gorm:"column:innovation_score" json:"innovation_score" form:"innovation_score"`
	Operating_risk_description       string       `gorm:"column:operating_risk_description" json:"operating_risk_description" form:"operating_risk_description"`
	Operating_risk_evaluation        string       `gorm:"column:operating_risk_evaluation" json:"operating_risk_evaluation" form:"operating_risk_evaluation"`
	Operating_risk_level             string       `gorm:"column:operating_risk_level" json:"operating_risk_level" form:"operating_risk_level"`
	Operating_risk_score             int          `gorm:"column:operating_risk_score" json:"operating_risk_score" form:"operating_risk_score"`
	Overall_score                    int          `gorm:"column:overall_score" json:"overall_score" form:"overall_score"`
	Manual_rating                    int          `gorm:"column:manual_rating" json:"manual_rating" form:"manual_rating"`
	Rating                           int          `gorm:"column:rating" json:"rating" form:"rating"`
	Total_views                      int          `gorm:"column:total_views" json:"total_views" form:"total_views"`
	Certification_status             int          `gorm:"column:certification_status" json:"certification_status" form:"certification_status"`
	Certification_status_description string       `gorm:"column:certification_status_description" json:"certification_status_description" form:"certification_status_description"`
	Is_published                     bool         `gorm:"column:is_published" json:"is_published" form:"is_published"`
	Location                         *model.Point `gorm:"column:location" json:"location" form:"location"`
	Source                           int          `gorm:"column:source" json:"source" form:"source"`
	Website                          string       `gorm:"column:website" json:"website" form:"website"`
	Org_type                         string       `gorm:"column:org_type" json:"org_type" form:"org_type"`
	Content_updated                  time.Time    `gorm:"column:content_updated" json:"content_updated" form:"content_updated"`
}

func (OrganizationOrganization) TableName() string {
	return "organization_organization"
}

func (PingOrganizationOrganization) TableName() string {
	return "ping_organization_organization"
}

func MigrateOrg(db *gorm.DB) map[int]int {
	orgMap := make(map[int]int)
	begin := time.Now()
	var orgList []OrganizationOrganization

	var offset int = 0
	var pagesize int = 500
	var myOrgId int

	for {
		fmt.Printf("begin find: offset: %d \n", offset)
		db.Limit(pagesize).Offset(offset).Order("created").Find(&orgList)
		fmt.Printf("begin find: offset: 0999 \n")
		var newOrgList []PingOrganizationOrganization
		for _, v := range orgList {

			p := PingOrganizationOrganization{}
			util.Copy(&v, &p)

			myOrgId = getOrgId()
			//	fmt.Printf("user mapping: %d -> %d \n", p.Id, myOrgId)
			orgMap[p.Id] = myOrgId
			p.Id = myOrgId
			newOrgList = append(newOrgList, p)

			tdb := db
			if p.Location == nil {
				tdb = db.Omit("location")
			}
			validateOrg(&v, db)
			p.Owner_id = singleton.GetUserIdMapping(p.Owner_id, fmt.Sprintf("orgId: %d", v.Id))
			// validate organization instance.
			if err := tdb.Create(&p).Error; err != nil {
				panic(err)
			}
		}
		offset += pagesize

		if len(orgList) < pagesize {
			break
		}
	}
	end := time.Now()
	fmt.Printf("org cost: %v \n", end.Sub(begin))

	return orgMap
}

func getOrgId() int {
	return int(atomic.AddInt32(&orgId, orgIdStep))
}

func validateOrg(v *OrganizationOrganization, db *gorm.DB) {

	// 规则一：
	ok, newDay := singleton.TimeBigSmall(v.Content_updated, v.Created, fmt.Sprintf(" Content_updated > create %d", v.Id))
	if !ok {
		singleton.WriteToGeneratesqlFile(fmt.Sprintf("// org规则一 \n update organization_organization set content_updated = %s' where id = %d;", newDay, v.Id))
	}

	//规则二：
	ok, _ = singleton.TimeBigSmalls(v.Updated, fmt.Sprintf("updated > Content_updated,Certification_time, %d", v.Id), v.Content_updated, v.Certification_time)
	if !ok {
		singleton.WriteToGeneratesqlFile(fmt.Sprintf("// org规则二 \n update organization_organization set updated = '%s' where id = %d;", newDay, v.Id))
	}

	//规则三：
	ok, _ = singleton.TimeBigSmall(v.Created, v.Established, fmt.Sprintf("Created > Established %d", v.Id))
	if !ok {
		singleton.WriteToGeneratesqlFile(fmt.Sprintf("// org规则三 \n update organization_organization set establish = '2010-11-11??' where id = %d;", v.Id))
	}

	//规则四：
	if v.Established.IsZero() {
		singleton.WriteToGeneratesqlFile(fmt.Sprintf("// org规则四 手动处理\n update organization_organization set established = '2010-11-11??' where id = %d;", v.Id))
	}

	//规则五：
	if !v.Certification_time.IsZero() {
		ok, newDay = singleton.TimeBigSmall(v.Certification_time, v.Created, fmt.Sprintf(" Certification_time > create %d", v.Id))
		if !ok {
			singleton.WriteToGeneratesqlFile(fmt.Sprintf("// org规则五 \n update organization_organization set Certification_time = '%s' where id = %d;", newDay, v.Id))
		}
	}

	// TODO: 要删除
	if v.Owner_id <= 0 {
		return
	}
	u := user.GetUser(v.Owner_id, db)
	//规则六：
	ok, _ = singleton.TimeBigSmall(v.Created, u.Date_joined, fmt.Sprintf("user Date_joined < org.created, %d", v.Id))
	if !ok {
		singleton.WriteToGeneratesqlFile(fmt.Sprintf("// org规则六 \n update organization_organization set created = '2020-11-11 11:11:11 手动修改' where id = %d;", v.Id))
	}

	// 全局检查
	var globalCheck []*model.GlobalTimeCheck
	globalCheck = append(globalCheck, &model.GlobalTimeCheck{v.Created, "created"},
		&model.GlobalTimeCheck{v.Updated, "updated"}, &model.GlobalTimeCheck{v.Content_updated, "content_updated"})

	if !v.Certification_time.IsZero() {
		globalCheck = append(globalCheck, &model.GlobalTimeCheck{v.Certification_time, "certification_time"})
	}
	for _, gtc := range globalCheck {
		// 全局检查
		b, adjustedDay := singleton.TimeGlobalCheck2(fmt.Sprintf("time: %s,  %d", gtc.Column, v.Id), gtc.CheckedTime)
		if !b {
			singleton.WriteToGeneratesqlFile(fmt.Sprintf("// org时间全局检查 \n select id, %s from  organization_organization  where id = %d;", gtc.Column, v.Id))
			singleton.WriteToGeneratesqlFile(fmt.Sprintf("update  organization_organization set  %s  =  '%s' where id = %d;", gtc.Column, adjustedDay, v.Id))
		}
	}

}
